\documentclass[twoside,colorback,accentcolor=tud4c,11pt]{tudreport}
\usepackage{ngerman}

\usepackage[utf8]{inputenc}

\usepackage{listings}
\lstset{
numbers=left,
numberstyle=\footnotesize,
frame=l,
breaklines=true,
basicstyle=\footnotesize,
showstringspaces=false
}
 
\usepackage[stable]{footmisc}
\usepackage[ngerman,pdfview=FitH,pdfstartview=FitV]{hyperref}

\usepackage{graphicx}
\usepackage{caption}
\usepackage{subcaption}

\usepackage{booktabs}
\usepackage{multirow}
\usepackage{longtable}

\newlength{\longtablewidth}
\setlength{\longtablewidth}{0.675\linewidth}

\title{Praktikum adaptive Computersysteme}
\subtitle{Ausarbeitung\\4. Phase: IP-Blöcke}
\subsubtitle{Wilko Kunert, Alexander Schleich}
\lowertitleback{\hfill\today}
\institution{Embedded Systems \& Applications}

\begin{document}
\maketitle

\tableofcontents

\chapter{Waveform}

In Phase 4 soll ein Dividierer in Hardware erzeugt und getestet werden. Mithilfe des Tools ``Xilinx CORE Generator'' lässt sich ein vorgefertigter Dividierer mit Pipeline für den FPGA anlegen. Darüber hinaus lässt sich aus dem Modell auch eine Verilognetzliste erzeugen. Aus dieser haben wir auch die Waveforms gewonnen. In Abbildung~\ref{fig:waveform} ist zu erkennen, dass die Latenz des Dividierers (hier mit 8 Bit Breite) 10 Takte beträgt. Auch der synthetisierte Dividierer arbeitet mit dieser Latenz, wie wir durch Messungen bestätigen konnten.

\begin{figure}[h]
\centering
\includegraphics[width=\linewidth]{graphics/waveform.png}
\caption{Waveform}
\label{fig:waveform}
\end{figure}

\chapter{HDL-Modell}

In Zeile 37 wird eine Instanz des Dividierers angelegt. Die Ein- und Ausgänge des Dividierers werden mit den internen Registern sowie der Clock und dem Reset-Signal verschaltet.

Die eigentliche Steuerung beginnt in Zeile 63. Dividend und Divisor bekommen Defaultwerte nach Reset.
Bei einem Schreibvorgang mit Codierung ``DIVIDEND'' wird ein temporäres Register beschrieben.
Bei einem zweiten Schreibvorgang mit Codierung ``DIVISOR'' werden die Register dividend und divisor (und damit auch
die Eingänge des Dividieres) auf die neuen Werte gesetzt. \\
In Zeile 82 wird auf eine Änderung der Dividiererausgänge reagiert und das codierte Ergebnis berechnet. \\
In Zeile 55 werden die Daten auf den DATAOUT Bus gelegt. Je nach Codierung der Adresse wird entweder das codierte Ergebnis,
das remd Register oder das quot Register ausgegeben.

\begin{figure}[h]
\centering
\begin{minipage}{\linewidth}
\lstset{language=Verilog,linewidth=0.9\linewidth,firstnumber=8}
\begin{lstlisting}
   module user(
	    CLK,
	    RESET,  
	    ADDRESSED,
	    WRITE,
	    DATAIN,
	    DATAOUT,
	    ADDRESS,
	    IRQ 
	    );

   // Eingaenge
   input           CLK;
   input           RESET;
   input           ADDRESSED;
   input           WRITE;
   input [31:0]    DATAIN;
   input [23:2]    ADDRESS;

   // Ausgaenge
   output [31:0]   DATAOUT;
   output          IRQ;

   wire 	   IRQ = 1'b0; // wird im Slave-Mode nicht gebraucht

   reg [15:0] result;
   reg [7:0] 	   dividend, divisor, tempDividend;
   wire [7:0] 	   quot, remd;

   PipelinedDivider pd
   (
	 	.dividend(dividend),
		.divisor(divisor),
		.quot(quot),
		.remd(remd),
		.clk(CLK),
		.rfd()
   );

\end{lstlisting}
\end{minipage}
\caption{user.v - Port- und Registerdeklaration, Dividierer Instanz}
\end{figure}

\begin{figure}[h]
\centering
\begin{minipage}{\linewidth}
\lstset{language=Verilog,linewidth=0.9\linewidth,firstnumber=46}
\begin{lstlisting}
   localparam REMD = 3'b001; //0x10000004
   localparam QUOT = 3'b010; //0x10000008
   localparam DIVIDEND = 3'b011; //0x1000000C
   localparam DIVISOR = 3'b000; // 0x10000000
   localparam READ_RESULT = 3'b100; //0x10000010
   
   // Beginn der Anwendung **************************************************

   // Ausgabedaten auf Bus legen
   assign DATAOUT = (ADDRESS[4:2] ==  READ_RESULT) ? result :
					  (ADDRESS[4:2] ==  QUOT) ? quot :
						(ADDRESS[4:2] ==  REMD) ? remd :		    										
				   		  32'hC0FEEE11;



   // Steuerung
   always @(posedge CLK or posedge RESET) begin
      // Initialisiere Register
      if (RESET) begin
	 			dividend  <= 32'hDEADBEEF;
	 			divisor  <= 32'hDEADBEEF;
	 // Schreibzugriff auf RC
      end 
			else if (ADDRESSED & WRITE) begin
				if(ADDRESS[4:2] == DIVIDEND) begin
					tempDividend <= DATAIN;		
				end			
				else if(ADDRESS[4:2] == DIVISOR) begin
					dividend <= tempDividend;
					divisor <= DATAIN;
				end
			end
   end

// result berechnen
   always @(remd or quot) begin
      result[15:8] = quot;
			result[7:0] = remd;
   end

endmodule
\end{lstlisting}
\end{minipage}
\caption{user.v - Ausgabe und Steuerung}
\end{figure}

\chapter{C-Programm}

In Zeile 31 und 32 werden Dividend (8) und Divisor (3) in die Hardware geschrieben. In Zeile 34, 35 und 36 werden 
die berechneten Werte ausgelesen und ausgegeben. \\
Beispielhaft wird nachfolgend noch 11 / 2 auf gleiche Weise durch die Hardware berechnet.

\begin{figure}[h]
\centering
\begin{minipage}{\linewidth}
\lstset{language=Verilog,linewidth=0.9\linewidth,firstnumber=30}
\begin{lstlisting}
	printf("teile 8 durch 3");
	rc[3] = 0x00000008;
	rc[0] = 0x00000003;
	printf("\r\n");
	printf("quot = %08x\n", rc[2]);
	printf("remd = %08x\n", rc[1]);
	printf("ergebnis (codiert) = %08x\n", rc[4]);

	printf("teile 11 durch 2");
	rc[3] = 0x0000000B;
	rc[0] = 0x00000002;
	printf("\r\n");
	printf("quot = %08x\n", rc[2]);
	printf("remd = %08x\n", rc[1]);
	printf("ergebnis (codiert) = %08x\n", rc[4]);
\end{lstlisting}
\end{minipage}
\caption{user.v - Ausgabe und Steuerung}
\end{figure}

\begin{figure}[h]
\centering
\includegraphics[width=.6\textwidth]{graphics/ausgabe.png}
\caption{Screenshot der Softwareausführung}
\label{fig:ausfuehrung}
\end{figure}

\end{document}
